package commandlineinterface;

import modeller.databasedesignmodel.DatabaseDesign;
import modeller.databasedesignmodel.servicedemand.IServiceDemand;
import modeller.databasedesignmodel.servicedemand.transaction.proceduralstatement.ProceduralStatementCalculatorVisitor;
import modeller.databasedesignmodel.servicedemand.transaction.proceduralstatement.IProceduralStatementServiceDemandCalculator;
import modeller.databasedesignmodel.servicedemand.transaction.TransactionServiceDemand;
import modeller.databasedesignmodel.servicedemand.transaction.sqlquery.calculatorfetcher.ISQLQueryServiceDemandCalculatorFetcher;
import modeller.databasedesignmodel.servicedemand.transaction.sqlquery.calculatorfetcher.SQLQueryServiceDemandCalculatorFetcher;
import modeller.databasedesignmodel.transaction.*;

import java.util.HashMap;
import java.util.LinkedList;

/**
 * Created by:  Jason Ye
 * Date:        28/12/2011
 * Time:        12:19
 */
public class ServiceDemandCalculator {

    private DatabaseDesign design;
    ISQLQueryServiceDemandCalculatorFetcher calculatorFetcher;
    IProceduralStatementServiceDemandCalculator psCalc;

    public ServiceDemandCalculator(DatabaseDesign design) {
        this.design = design;
        this.calculatorFetcher = new SQLQueryServiceDemandCalculatorFetcher(design);
        this.psCalc = new ProceduralStatementCalculatorVisitor(design, calculatorFetcher);
    }

    public HashMap<Transaction, IServiceDemand> calculate() {

        HashMap<Transaction, IServiceDemand> designDemands = new HashMap<Transaction, IServiceDemand>();
        // calculate demand for each transaction, for each relation
        for (Transaction transaction : design.getTransactions()) {

            IServiceDemand demand = calculate(transaction);

            designDemands.put(transaction, demand);
        }

        return designDemands;

    }

    private IServiceDemand calculate(Transaction transaction) {

        LinkedList<IServiceDemand> demands = new LinkedList<IServiceDemand>();
        for (IProceduralStatement ps : transaction.getProceduralStatements()) {
            demands.add(ps.acceptCalculation(psCalc));
        }

        return new TransactionServiceDemand(demands);
    }

}
